import os
import sys
import struct
import binascii
import numpy as np
import cv2
import ffmpeg

def read_bin_files(directory):
    """读取指定目录下所有 .bin 文件"""
    bin_files = [f for f in os.listdir(directory) if f.endswith('.bin')]
    bin_data = []
    for file in bin_files:
        with open(os.path.join(directory, file), 'rb') as f:
            bin_data.append((file, f.read()))
    return bin_data

def create_frame(source_addr, dest_addr, data, max_payload_size):
    """创建一帧数据"""
    # 帧结构：帧首定界符 (1字节) + 目的地址 (1字节) + 源地址 (1字节) + 长度 (2字节) + 载荷 + CRC (4字节)
    frame_header = struct.pack('B B B H', 0xCA, dest_addr, source_addr, len(data))  # 帧首、目的地址、源地址、长度
    crc = struct.pack('I', binascii.crc32(data))  # CRC校验
    frame = frame_header + data + crc
    return frame

def encode_bin_files(bin_data, mtu, output_file, video_length):
    """将二进制文件编码为视频帧并保存为 MP4 格式"""
    frames = []
    source_addr = 0x01  # 假设源地址为 1
    for dest_addr, (filename, data) in enumerate(bin_data, start=1):  # 每个文件对应一个目的地址
        for i in range(0, len(data), mtu - 9):  # 减去9字节头部和校验部分
            payload = data[i:i + (mtu - 9)]
            frame = create_frame(source_addr, dest_addr, payload, mtu - 9)
            frames.append(frame)

    # 使用随机生成的图像作为视频的帧图像
    # 使用 OpenCV 生成并保存帧
    frame_width, frame_height = 320, 240  # 分辨率
    fps = 30  # 帧率
    num_frames = int(fps * (video_length / 1000))  # 视频的总帧数

    # 创建视频写入器
    out = cv2.VideoWriter(output_file, cv2.VideoWriter_fourcc(*'mp4v'), fps, (frame_width, frame_height))

    for frame_index in range(num_frames):
        # 生成随机图像
        image = np.random.randint(0, 256, (frame_height, frame_width, 3), dtype=np.uint8)
        out.write(image)

    # 释放视频写入器
    out.release()
    print(f"编码完成，输出文件：{output_file}")

def main():
    if len(sys.argv) != 5:
        print("用法: python encode.py <文件目录> <最大传输单元(MTU)> <输出文件> <视频时长(ms)>")
        sys.exit(1)

    directory = sys.argv[1]  # 输入目录
    mtu = int(sys.argv[2])   # 最大传输单元 (MTU)
    output_file = sys.argv[3]  # 输出文件名
    video_length = int(sys.argv[4])  # 视频时长

    bin_data = read_bin_files(directory)
    encode_bin_files(bin_data, mtu, output_file, video_length)

if __name__ == "__main__":
    main()
